import logging  # 日志记录
import os  # 操作系统接口
import threading  # 线程管理
from datetime import datetime  # 日期时间处理

from flask import Flask, jsonify, request  # Web服务框架
from waitress import serve

# 从config.py导入配置
from config import (
    LOG_DIR, OUTPUT_DIR,
    AUDIO_GEN_PORT, VIDEO_GEN_PORT,
    WECHAT_WEBHOOK_URL
)

# 导入并配置日志
from logger_setup import setup_logging, logger
setup_logging() # 初始化日志系统

# 从 task_scheduler.py 导入任务队列、服务器队列和调度函数
from task_scheduler import task_queue, server_queue, dispatch_tasks, add_task_to_queue

# --- Flask 应用初始化 ---
app = Flask(__name__)  # 创建Flask应用实例
os.makedirs(OUTPUT_DIR, exist_ok=True)  # 确保输出文件目录存在
# --- Flask 应用初始化结束 ---

@app.route("/notify", methods=["POST"])
def handle_notification():
    """
    处理通知API端点，接收音视频合成任务请求
    
    请求体格式（JSON）:
    {
        "id": "任务ID",
        "name": "任务名称",
        "video_url": "原始视频URL",
        "audio_url": "音频提示URL",
        "text": "合成文本内容"
    }
    
    Returns:
        JSON响应，状态码202表示任务已被接受并排队
    """
    if not request.is_json:
        logger.warning("请求体不是JSON")
        return jsonify({"error": "请求需要是JSON格式"}), 400

    data = request.get_json()
    logger.info(f"接收到原始数据: {data}")

    # 获取请求的来源IP
    request_ip = request.remote_addr
    logger.info(f"请求来源 IP: {request_ip}")

    # 判断是否为内部请求 (简单示例，假设192.168.1.X为内部)
    # 注意：如果应用部署在反向代理后面，request.remote_addr 可能不是真实客户端IP。
    # 需要根据实际部署情况调整，例如检查 X-Forwarded-For 头部。
    is_internal_request = request_ip.startswith("192.168.1.")
    data['is_internal_request'] = is_internal_request # 将IP信息添加到任务数据中
    logger.info(f"请求类型判定: {'内部' if is_internal_request else '外部'}")

    required_fields = ["id", "name", "video_url", "audio_url", "text"]
    missing_fields = [field for field in required_fields if field not in data]

    if missing_fields:
        logger.warning(f"请求中缺少字段: {', '.join(missing_fields)}")
        return jsonify({"error": f"缺少字段: {', '.join(missing_fields)}"}), 400
    
    try:
        task_id = data["id"]

        if add_task_to_queue(data.copy()):
            logger.info(f"任务 ID: {task_id} 已成功加入任务队列。") # 确认日志
            return jsonify({
                "message": f"任务 ID '{task_id}' 已接收并加入队列，等待处理。",
                "status": "排队中",
                "id": task_id
            }), 202
        else:
            # 如果 add_task_to_queue 返回 False，说明任务因重复未被添加
            logger.info(f"任务 ID: {task_id} 因在任务池中已存在而未被重复添加。")
            return jsonify({
                "message": f"任务 ID '{task_id}' 已存在于当前任务池中，未被重复添加。",
                "status": "已在队列中", # 或者其他合适的表示状态
                "id": task_id
            }), 200 # 或者 409 Conflict，具体根据API设计规范
        
    except KeyError as key_error:
        logger.warning(f"解析任务ID时出错 (缺少键): {key_error}")
        return jsonify({"error": f"请求JSON中缺少 'id' 键或关键信息: {key_error}"}), 400
    except Exception as unknown_handle_notification_exception:
        logger.error(f"启动后台处理时发生未知错误: {unknown_handle_notification_exception}", exc_info=True)
        return jsonify({"error": f"启动后台处理时发生未知错误: {str(unknown_handle_notification_exception)}"}), 500

if __name__ == "__main__":
    dispatcher_thread = threading.Thread(target=dispatch_tasks, daemon=True)
    dispatcher_thread.start()
    
    logger.info(f"AI数字人合成服务启动，监听端口: 5001")
    serve(app, host="0.0.0.0", port=5001)